package com.rq.base.net;

import android.os.Handler;
import android.os.Looper;

import com.rq.base.net.impl.HttpConstantImpl;
import com.rq.base.net.impl.HttpInnerListener;
import com.rq.base.net.impl.UrlImpl;
import com.rq.base.ui.impl.BaseView;
import com.rq.base.util.LOG;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class HTTP {

    private volatile static HTTP mHttp;
    private static Class<? extends HttpProxy> clazz;
    private HttpProxy mHttpProxy;

    public static void setProxy(Class<? extends HttpProxy> c) {
        HTTP.clazz = c;
    }

    private HTTP() {
        if (clazz != null) {
            try {
                mHttpProxy = clazz.newInstance();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }
    }

    public static HTTP get() {
        if (mHttp == null) {
            synchronized (HTTP.class) {
                if (mHttp == null) {
                    mHttp = new HTTP();
                }
            }
        }
        return mHttp;
    }

    /**
     * @param impl
     * @param data  数据key 以“{”开头 则表示拼接到同名 url位置
     *              以"["开头的拼接到请求头中
     * @param clazz
     * @param view
     * @param <T>
     */
    public <T> void post(UrlImpl impl, Map<String, Object> data, final Class<T> clazz, BaseView view) {
        String url = getRealUrl(impl, data);
        Map<String, String> heads = new HashMap<>();

        if (data != null) {
            Iterator<String> iterator = data.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                if (key.startsWith("[")) {
                    heads.put(key.substring(1), String.valueOf(data.get(key)));
                    iterator.remove();
                }
            }
            if (impl.paramAppend()) {
                StringBuffer sb = new StringBuffer(url);
                if (data.size() > 0) {
                    sb.append("?");
                    Iterator<String> it2 = data.keySet().iterator();
                    while (it2.hasNext()) {
                        try {
                            String key = it2.next();
                            sb.append(URLEncoder.encode(key, "utf-8"));
                            sb.append(key);
                            sb.append("=");
                            sb.append(data.get(key));
                            if (it2.hasNext()) {
                                sb.append("&");
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
                url = sb.toString();
            }

        }
        if (mHttpProxy != null) {
            mHttpProxy.post(url, heads, data, clazz, view, new RequestType(impl));
        } else {
            send(url, "POST", heads, data, clazz, view, impl);
        }
    }

    public <T> void get(UrlImpl impl, Map<String, Object> data, final Class<T> clazz, BaseView view) {
        String url = getRealUrl(impl, data);
        Map<String, String> heads = new HashMap<>();
        if (data != null) {
            Iterator<String> iterator = data.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                if (key.startsWith("[")) {
                    heads.put(key.substring(1), String.valueOf(data.get(key)));
                    iterator.remove();
                }
            }
            StringBuffer sb = new StringBuffer(url);
            if (data.size() > 0) {
                sb.append("?");
                Iterator<String> it2 = data.keySet().iterator();
                while (it2.hasNext()) {
                    try {
                        String key = it2.next();
                        sb.append(URLEncoder.encode(key, "utf-8"));
                        sb.append(key);
                        sb.append("=");
                        sb.append(data.get(key));
                        if (it2.hasNext()) {
                            sb.append("&");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            url = sb.toString();
        }
        if (mHttpProxy != null) {
            mHttpProxy.get(url, heads, data, clazz, view, new RequestType(impl));
        } else {
            send(url, "GET", heads, data, clazz, view, impl);
        }
    }

    Handler mainHandler = new Handler(Looper.getMainLooper());

    public void download(String path, String savePath, Map<String, Object> data, HttpThreadManager.DownListener listener) {
        if (mHttpProxy != null) {
            Map<String, String> heads = new HashMap<>();
            if (data != null) {
                Iterator<String> iterator = data.keySet().iterator();
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    if (key.startsWith("[")) {
                        heads.put(key.substring(1), String.valueOf(data.get(key)));
                        iterator.remove();
                    }
                }
            }
            mHttpProxy.download(path, savePath, heads, data, listener);
        } else {
            HttpThreadManager.get().download(path, data, savePath, listener);
        }
    }

    private <T> void dealResponse(Class<T> clazz, BaseView view, String json, UrlImpl impl) {
        LOG.e("HTTP", "91:" + json);
        Object obj = NetworkRequestJudge.get().toBean(json, clazz);
        if (NetworkRequestJudge.get().isOk(obj)) {
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    view.onResponseSucceed(new RequestType(impl), obj);
                }
            });
        } else {
            mainHandler.post(new Runnable() {
                @Override
                public void run() {
                    view.onResponseError(new RequestType(impl), obj);
                }
            });
        }
    }

    private <T> void dealResponseError(BaseView view, String errorMsg, UrlImpl impl) {
        LOG.e("HTTP", "96:" + errorMsg);
        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                view.onResponseError(new RequestType(impl), "请求异常:" + errorMsg);
            }
        });
    }

    private String getRealUrl(UrlImpl impl, Map<String, Object> data) {
        String url = impl.getFullUrl();
        if (!url.startsWith("http")) {
            url = HttpConstantImpl.getBaseUrl() + url;
        }
        if (data != null) {
            Iterator<String> it = data.keySet().iterator();
            while (it.hasNext()) {
                String key = it.next();
                if (key.contains("{")) {
                    url = url.replace(key, String.valueOf(data.get(key)));
                    it.remove();
                }
            }
        }
        return url;
    }

    private <T> void send(String path, String way, Map<String, String> head, Map<String, Object> map, Class<T> clazz, BaseView view, UrlImpl impl) {
        HttpSender.send(path, way, head, new HashMap<>(map), new HttpInnerListener() {
            @Override
            public void onString(String json) {
                dealResponse(clazz, view, json, impl);
            }

            @Override
            public void onEmptyResponse(String errorMsg) {
                dealResponseError(view, errorMsg, impl);
            }
        }, null);
    }
}
